<template>
  <el-card>
    <el-form :inline="true" class="search-form">
      <el-form-item label="角色名称:">
        <el-input v-model="keyword" placeholder="请输入角色名称"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="searchHandler" :disabled="keyword === ''">搜索</el-button>
        <el-button type="default" icon="Refresh" @click="resetHandler">重置</el-button>
      </el-form-item>
    </el-form>
  </el-card>

  <el-card class="el-card-main">
    <el-button type="primary" icon="Plus" @click="addRole">添加角色</el-button>
    <el-table :data="roleArr" border>
      <el-table-column type="index" label="序号" width="60" align="center" />
      <el-table-column prop="id" label="ID" width="120" align="center" />
      <el-table-column prop="roleName" label="角色名称" align="center" />
      <el-table-column prop="createTime" label="创建时间" align="center" />
      <el-table-column prop="updateTime" label="更新时间" align="center" />
      <el-table-column label="操作" width="150" align="center">
        <template #default="{ row, index }">
          <el-button @click="assignPermissions(row)" type="primary" size="small" icon="Lock" circle></el-button>
          <el-button @click="updateRole(row)" type="warning" size="small" icon="Edit" circle></el-button>
          <el-button @click="deleteRole(row)" type="danger" size="small" icon="Delete" circle></el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      @current-change="currentPageChange"
      @size-change="pageSizeChange"
      v-model:page-size="limit"
      v-model:current-page="pageNo"
      :page-sizes="[5, 10, 20, 50, 100, 200]"
      :background="true"
      layout="prev, pager, next, jumper, ->, sizes, total"
      :total="total"
    />
  </el-card>

  <el-dialog v-model="addOrUpdate" :title="roleParams.id ? '更新角色' : '添加角色'" width="500">
    <el-form :model="roleParams" ref="roleFormEle" :rules="rules">
      <el-form-item label="角色名称" prop="roleName">
        <el-input v-model="roleParams.roleName" />
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="confirm">确认</el-button>
      </div>
    </template>
  </el-dialog>

  <el-drawer v-model="assignPermissionsDrawer" direction="rtl" title="分配权限">
    <template #default>
      <h4 disabled>权限列表</h4>
      <el-tree
        ref="tree"
        :data="menuArr"
        show-checkbox
        node-key="id"
        default-expand-all
        :default-checked-keys="defaultChangedKeys"
        :props="defaultProps"
      />
    </template>
    <template #footer>
      <div style="flex: auto">
        <el-button @click="cancelAssignPermission">取消</el-button>
        <el-button type="primary" @click="confirmAssignPermission">确认</el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import { MenuData, MenuResponseData, RoleData, RoleResponseData } from '@/api/acl/role/types';
import { ElMessageBox } from 'element-plus';

// 当前页码
const pageNo = ref<number>(1);
// 当前页数据数
const limit = ref<number>(5);
// 总数据条数
const total = ref<number>(0);
// 角色列表
const roleArr = ref<RoleData[]>([]);
// 所有权限数组
const menuArr = ref<MenuData[]>([]);
// 属性控件元素
const tree = ref();
// 添加角色表单元素
const roleFormEle = ref();
//默认选中的数组id
const defaultChangedKeys = ref<number[]>([]);
// 搜索关键字
const keyword = ref<string>('');
// layout相关配置
const setting = useLayoutSettingStore();
// 显示添加窗口
const addOrUpdate = ref<boolean>(false);
// 显示分配角色抽屉
const assignPermissionsDrawer = ref<boolean>(false);
// 添加角色参数
const roleParams = reactive<RoleData>({
  roleName: '',
});
//树形控件的配置选项
const defaultProps = {
  children: 'children',
  label: 'name',
};

onMounted(() => {
  getRoles();
});
// 加载数据
const getRoles = async (pager = 1) => {
  pageNo.value = pager;
  const result: RoleResponseData = await reqGetAllRoles(pageNo.value, limit.value, keyword.value);
  if (result.code === 200) {
    roleArr.value = result.data.records;
    pageNo.value = result.data.current;
    limit.value = result.data.size;
    total.value = result.data.total;
  }
};
// 当前页发生改变触发
const currentPageChange = () => {
  getRoles(pageNo.value);
};
// 页面数据数发生改变触发
const pageSizeChange = () => {
  getRoles();
};
// 添加角色
const addRole = () => {
  addOrUpdate.value = true;
  Object.assign(roleParams, {
    roleName: '',
    id: 0,
  });
  //清空校验消息
  nextTick(() => {
    roleFormEle.value.clearValidate(['roleName']);
  });
};
// 取消添加或更新
const cancel = () => {
  addOrUpdate.value = false;
};
// 确定添加或者更新
const confirm = async () => {
  // 表单校验，通过的话继续
  await roleFormEle.value.validate();

  const result: any = await reqAddOrUpdateRole(roleParams);
  if (result.code === 200) {
    ElMessage.success(roleParams.id ? '更新成功' : '添加成功');
    getRoles(roleParams.id ? pageNo.value : 1);
    addOrUpdate.value = false;
  } else {
    ElMessage.error(roleParams.id ? '更新失败' : '添加失败');
  }
};
// 分配权限
const assignPermissions = async (row: RoleData) => {
  Object.assign(roleParams, row);
  const result: MenuResponseData = await reqGetPermissionByRoleId(row.id as number);
  if (result.code === 200) {
    assignPermissionsDrawer.value = true;
    menuArr.value = result.data;
    defaultChangedKeys.value = filterChangedKeys(menuArr.value, []);
  }
};
// 递归过滤出拥有的权限菜单
const filterChangedKeys = (allData: any, initArr: any) => {
  allData.forEach((item: any) => {
    if (item.select && item.level === 4) {
      initArr.push(item.id);
    }
    if (item.children && item.children.length > 0) {
      filterChangedKeys(item.children, initArr);
    }
  });
  return initArr;
};
// 更新角色
const updateRole = (row: RoleData) => {
  addOrUpdate.value = true;
  Object.assign(roleParams, row);
  //清空校验消息
  nextTick(() => {
    roleFormEle.value.clearValidate(['roleName']);
  });
};
// 删除角色
const deleteRole = (row: RoleData) => {
  ElMessageBox.confirm(`确定要删除【${row.roleName}】这个角色吗？`, {
    title: '提示',
  })
    .then(async () => {
      const result: any = await reqDeleteRole(row.id as number);
      if (result.code === 200) {
        ElMessage.success('删除成功');
        getRoles(roleArr.value.length >= 1 ? pageNo.value : pageNo.value - 1);
      } else {
        ElMessage.error('删除失败');
      }
    })
    .catch(() => {
      ElMessage.success('已取消删除');
    });
};
// 搜索角色
const searchHandler = () => {
  getRoles();
  keyword.value = '';
};
// 重置
const resetHandler = () => {
  setting.refresh = !setting.refresh;
};
// 取消分配权限
const cancelAssignPermission = () => {
  assignPermissionsDrawer.value = false;
};
// 确定分配权限
const confirmAssignPermission = async () => {
  const roleId = roleParams.id as number;

  const permissionId = tree.value.getCheckedKeys().concat(tree.value.getHalfCheckedKeys());

  const result: any = await reqAssignPermission(roleId, permissionId);
  if (result.code === 200) {
    assignPermissionsDrawer.value = false;
    ElMessage.success('分配权限成功');
    window.location.reload();
  } else {
    ElMessage.error('分配权限失败');
  }
};
// 自定义角色校验
const validatorRoleName = (rule: any, value: any, callBack: any) => {
  if (value === '') {
    callBack('角色名称不能为空');
  } else if (value.trim().length <= 2) {
    callBack('角色名称长度不能小于两位');
  } else {
    callBack();
  }
};
// 自定义校验规则
const rules = reactive({
  roleName: [{ required: true, trigger: 'blur', validator: validatorRoleName }],
});
</script>

<style lang="scss" scoped>
.search-form {
  display: flex;
  justify-content: space-between;
  flex-wrap: nowrap;
  .el-form-item {
    margin: 0;
  }
}
.el-card-main {
  margin-top: 10px;

  .el-table {
    margin: 10px 0;
    height: calc(100vh - $base-tabbar-height - 230px);
  }
}
</style>
